<%--
  Created by IntelliJ IDEA.
  User: lujw
  Date: 2017/6/14
  Time: 18:15
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/common/hospital_token.jsp"%>
<%!
    /**
     * 推送地址
     */
    private static String pushUrl;

    /**
     * 通知正文html头
     */
    private static final String htmlHeader = "<html><meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1'>";

    /**
     * 通知正文html尾
     */
    private static final String htmlFooter = "</html>";

    /**
     * 发送通知
     * @param token
     * @param notice
     * @return
     */
    public Message create(HospitalToken token, HospitalNotice notice) {
        Message msg = new Message();
        if (Objects.isNull(notice)) {
            ErrcodeUtil.setErrcode(msg, ErrcodeUtil.FAILURE);
            return msg;
        }
        if (Objects.isNull(notice.getAttachment()))
            notice.setAttachment("[]");
        if (Objects.isNull(notice.getImg()))
            notice.setImg("[]");
        //app发送的消息添加html标签头尾
        try {
            notice.setContent(Base64.getEncoder().encodeToString((htmlHeader + new String(Base64.getDecoder().decode(notice.getContent().getBytes(StringUtil.UTF8)), StringUtil.UTF8) + htmlFooter).getBytes(StringUtil.UTF8)));
        } catch (UnsupportedEncodingException e) {}
        notice.setFromClient("app");
        Integer uid = token.getUid();
        notice.setOperatorId(uid);
        List<String> names = QBuilder.db("basedb").select("name").from("HospitalUser").where(new Where("id=", uid).and("status=", ConstantUtil.STATUS_ENABLE)).page(1, 1).query().getResultObj();
        if (names.size() == 0)
            notice.setOperatorName("暂无");
        else
            notice.setOperatorName(names.get(0));
        //解密发送范围
        String receiver = notice.getReceiver();
        if (Objects.nonNull(receiver)) {
            notice.setReceiver(Tools.decryptStr(receiver));
        }
        Integer id = (Integer) DBTools.db("basedb").addItem(notice);
        if (Objects.isNull(id)) {
            msg.setErrcodeAndErrmsg(30099, "发送失败");
            return msg;
        }
        Integer hospital = notice.getHospital();
        Map receiverMap = JSONUtil.fromJson(notice.getReceiver(), new TypeReference<Map>(){});
        Set<Integer> userIdSet = getUserIdSetByReceiver(receiverMap, hospital);
        if (Objects.nonNull(userIdSet) && userIdSet.size() > 0) {
            List<HospitalNoticeFeedback> feedbackList = new ArrayList<HospitalNoticeFeedback>();
            Iterator<Integer> iterator = userIdSet.iterator();
            while (iterator.hasNext()) {
                HospitalNoticeFeedback feedback = new HospitalNoticeFeedback();
                feedback.setUserId(iterator.next());
                feedback.setNoticeId(id);
                feedback.setHospital(hospital);
                feedbackList.add(feedback);
            }
            DBTools.db("basedb").addItem(feedbackList);
        }
        Map outMap = new HashMap();
        outMap.put("id", id);
        msg.put("data", outMap);
        msg.setErrmsg("发送成功");
        //开辟一个线程推送
        new NoticePushThread(id, notice.getHospital(), pushUrl).start();
        return msg;
    }

    /**
     * 发送通知线程
     */
    class NoticePushThread extends Thread {
        /**
         * 参数
         */
        private Map<String, String> params;

        /**
         * 通知id
         */
        private Integer noticeId;

        /**
         * 医院编号
         */
        private Integer hospital;

        /**
         * 推送地址
         */
        private String pushUrl;

        public NoticePushThread(Integer noticeId, Integer hospital, String pushUrl) {
            this.noticeId = noticeId;
            this.hospital = hospital;
            this.pushUrl = pushUrl;
            init();
        }

        private void init() {
            params = new HashMap<>();
            params.put("notice_id", noticeId + "");
            params.put("hospital", hospital + "");
        }

        @Override
        public void run() {
            HttpUtil.encryptPost(pushUrl, params);
        }
    }

    /**
     * 根据发送范围以及hospital获得userId的Set集合
     * @param receiverMap 发送范围
     * @param hospital
     * @return
     */
    public Set<Integer> getUserIdSetByReceiver(Map receiverMap, Integer hospital) {
        Set<Integer> userIdSet = new HashSet<Integer>();
        if (Objects.isNull(receiverMap) || Objects.isNull(hospital))
            return userIdSet;
        List<Map> deptList = (List<Map>)receiverMap.get("dept");
        boolean isAllUser = false;
        //判断是否是全院发送
        if (Objects.nonNull(deptList)) {
            for (int i = 0, length = deptList.size(); i < length; i++) {
                Map dept = deptList.get(i);
                if ("-1".equals(Tools.getDesc(dept.get("id")))) {
                    isAllUser = true;
                    break;
                }
            }
        }
        List<Integer> userIdList = null;
        if (isAllUser) {
            //如果是全院发送则查出该医院全部员工id
            userIdList = QBuilder.db("basedb").select("id").from("HospitalUser").where(new Where("hospital=", hospital).and("status=", ConstantUtil.STATUS_ENABLE)).query().getResultObj();
            userIdSet.addAll(userIdList);
        } else {
            //如果不是全院发送则遍历user,dept,label查出员工id
            List<Map> userList = (List<Map>)receiverMap.get("user");
            //user
            if (Objects.nonNull(userList)) {
                for (int i = 0, length = userList.size(); i < length; i++) {
                    userIdSet.add(Tools.getInt(String.valueOf(userList.get(i).get("id"))));
                }
            }
            //dept,label
            List<Map> labelList = (List<Map>)receiverMap.get("label");
            if ((Objects.nonNull(deptList) && deptList.size() > 0) || (Objects.nonNull(labelList) && labelList.size() > 0)) {
                List<Map> allDeptList = QBuilder.db("basedb").select("new map(id as dept_id, parent as parent)").from("Dept").where(new Where("hospital=", hospital).and("status=", ConstantUtil.STATUS_ENABLE).and("type=", ConstantUtil.DEPT_LINK)).query().getResultObj();
                List<Map> deptUserList = QBuilder.db("basedb").select("new map(du.deptId as dept_id, u.id as user_id)").from("HospitalDeptUser du, HospitalUser u").where(new Where("du.hospital=", hospital).and("du.status=", ConstantUtil.STATUS_ENABLE).and("u.status=", ConstantUtil.STATUS_ENABLE).and("u.hospital=", hospital).and("du.userId=u.id")).query().getResultObj();
                if (Objects.nonNull(deptList) && deptList.size() > 0) {
                    for (int i = 0, length = deptList.size(); i < length; i++) {
                        Map deptMap = deptList.get(i);
                        Integer deptId = (Integer) deptMap.remove("id");
                        for (int j = 0, dLength = deptUserList.size(); j < dLength; j++) {
                            Map deptUserMap = deptUserList.get(j);
                            if (deptId.equals(deptUserMap.get("dept_id"))) {
                                userIdSet.add((Integer)deptUserMap.get("user_id"));
                            }
                        }
                        deptMap.put("dept_id", deptId);
                    }
                    getDeptUserId(deptList, allDeptList, deptUserList, userIdSet);
                }
                if (Objects.nonNull(labelList) && labelList.size() > 0) {
                    StringBuilder builder = new StringBuilder("-1");
                    for (int i = 0, length = labelList.size(); i < length; i++) {
                        builder.append(",");
                        builder.append(labelList.get(i).get("id"));
                    }
                    //查出标签直接关联的员工id
                    userIdList = QBuilder.db("basedb").select("u.id").from("HospitalUser u, HospitalLabel l, HospitalLabelMember lm").where(new Where("l.hospital=", hospital).and("l.status=", ConstantUtil.STATUS_ENABLE).and("l.id=lm.labelId").and("l.id in (" + builder.toString() + ")").and("lm.hospital=", hospital).and("lm.status=", ConstantUtil.STATUS_ENABLE).and("lm.type=", ConstantUtil.HOSPITAL_LABEL_USER).and("u.hospital=", hospital).and("u.status=", ConstantUtil.STATUS_ENABLE).and("u.id=lm.memberId")).query().getResultObj();
                    userIdSet.addAll(userIdList);
                    //查出标签下的科室关联的员工id
                    deptList = QBuilder.db("basedb").select("new map(d.id as dept_id)").from("HospitalLabel l, HospitalLabelMember lm, Dept d").where(new Where("l.hospital=", hospital).and("l.status=", ConstantUtil.STATUS_ENABLE).and("l.id=lm.labelId").and("l.id in (" + builder.toString() + ")").and("lm.hospital=", hospital).and("lm.status=", ConstantUtil.STATUS_ENABLE).and("lm.type=", ConstantUtil.HOSPITAL_LABEL_DEPT).and("d.hospital=", hospital).and("d.status=", ConstantUtil.STATUS_ENABLE).and("d.id=lm.memberId").and("d.type=", ConstantUtil.DEPT_LINK)).query().getResultObj();
                    getDeptUserId(deptList, allDeptList, deptUserList, userIdSet);
                }
            }
        }
        return userIdSet;
    }

    /**
     * 获取科室列表下的所有员工id
     * @param receiverList 发送范围的科室
     * @param deptList 医院下所有的科室
     * @param deptUserList 科室与员工的关系
     * @param userIdSet 员工id集合
     */
    public void getDeptUserId(List<Map> receiverList, List<Map> deptList, List<Map> deptUserList, Set<Integer> userIdSet) {
        if (Objects.isNull(receiverList) || receiverList.size() == 0)
            return;
        for (int i = 0, length = receiverList.size(); i < length; i++) {
            Map map = receiverList.get(i);
            String deptId = Tools.getDesc(map.get("dept_id"), "");
            List<Map> childList = (List<Map>)map.get("child_dept");
            for (int j = 0, aLength = deptList.size(); j < aLength; j++) {
                Map deptMap = deptList.get(j);
                if (deptId.equals(deptMap.get("parent"))) {
                    if (Objects.isNull(childList)) {
                        childList = new ArrayList<Map>();
                        map.put("child_dept", childList);
                    }
                    childList.add(deptMap);
                    Integer childDeptId = (Integer)deptMap.get("dept_id");
                    for (int k = 0, dLength = deptUserList.size(); k < dLength; k++) {
                        Map deptUserMap = deptUserList.get(k);
                        if (childDeptId.equals(deptUserMap.get("dept_id")))
                            userIdSet.add((Integer)deptUserMap.get("user_id"));
                    }
                }
            }
            getDeptUserId(childList, deptList, deptUserList, userIdSet);
        }
    }
%>
<%
    //推送地址
    if (pushUrl == null) {
        pushUrl = "http://" + request.getServerName() + ":" + request.getServerPort() + "/v3/hospital_notice/push.jsp";
    }
    HospitalNotice notice = HospitalNotice.fromMap(parameters, HospitalNotice.class);
    Tools.encryptPrint(out, create(token, notice));
%>
